<template>
  <div class="login sg-flex-column">
    <sg-header @back="$router.go(-1)">Sghen三行</sg-header>
    <div class="sg-flex-one" style="overflow-x: hidden; overflow-y: auto" sg-scroll="vertical_stop">
      <sg-form ref="form" :formData="formData" :formRules="formRules">
        <template #captchaValue>
          <div class="login-captcha">
            <input v-model="formData.captchaValue" v-focus-within />
            <span
              v-if="captcha.id"
              class="svg-box"
              v-html="captcha.svgData"
              @click="onGetCaptcha"
            ></span>
          </div>
        </template>
        <template #code>
          <div class="login-code">
            <input v-model="formData.code" v-focus-within />
            <span class="code-divider"></span>
            <span v-show="countdown > 0" class="code-countdown">{{ countdownText }}</span>
            <sg-button
              v-show="countdown <= 0"
              type="text"
              :isLoading="smsLoading"
              @click="onGetSmsCode"
              >获&nbsp;取</sg-button
            >
          </div>
        </template>
        <template #loginType>
          <div class="login-type">
            <div class="left">
              <sg-button
                v-show="formData.loginType !== 'create'"
                type="text"
                @click="onChangeLoginType('code')"
                >{{ formData.loginType === 'pw' ? '短信登陆' : '密码登陆' }}</sg-button
              >
            </div>
            <div class="right">
              <sg-button
                v-show="formData.loginType !== 'code'"
                type="text"
                @click="onChangeLoginType('create')"
                >{{ formData.loginType === 'pw' ? '账号注册' : '已有账号？' }}</sg-button
              >
            </div>
          </div>
        </template>
        <sg-button
          class="login-button"
          type="primary"
          :isLoading="isRequesting"
          @click="onSubmit"
          >{{
            formData.loginType === 'create' ? '注&nbsp;&nbsp;册' : '登&nbsp;&nbsp;录'
          }}</sg-button
        >
      </sg-form>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { mapState, mapActions } from 'pinia'
import { useAuthStore } from '@/store/index'
import { isPhone } from '@/utils/verification'
import { apiURL, apiGetData, apiPostData } from '@/api'

export default defineComponent({
  name: 'PageLogin',

  data() {
    return {
      isRequesting: false,
      formData: {
        name: '',
        phone: null,
        pw: '',
        code: '',
        loginType: 'pw',
        captchaValue: ''
      },
      formRules: [
        {
          key: 'phone',
          label: '手机号码',
          required: true,
          hidden: false,
          validator: (v: any, rule: any) => {
            if (this.isNormalLogin) {
              return v ? '' : '请输入' + rule.label
            }
            return isPhone(v) ? '' : '请输入' + rule.label
          },
          _error: ''
        },
        {
          key: 'name',
          label: '昵称',
          required: false,
          hidden: true,
          validator: (v: any, rule: any) => {
            return v ? '' : '请输入' + rule.label
          },
          _error: ''
        },
        {
          key: 'pw',
          label: '密码',
          required: true,
          hidden: false,
          inputType: 'password',
          validator: (v: any, rule: any) => {
            if (!v) {
              return '请输入' + rule.label
            } else {
              return v.length < 6 || v.length > 20 ? '密码长度为6~20字符' : ''
            }
          },
          _error: ''
        },
        {
          key: 'pw2',
          label: '重复密码',
          required: false,
          hidden: true,
          inputType: 'password',
          validator: (v: any, rule: any) => {
            if (!v) {
              return '请输入' + rule.label
            } else if (v.length < 6 || v.length > 20) {
              return '密码长度为6~20字符'
            } else {
              return (this.formData as any).pw !== v ? '两次密码不一致' : ''
            }
          },
          _error: ''
        },
        {
          key: 'captchaValue',
          slot: true,
          label: '图形验证',
          hidden: true,
          required: false,
          validator: (v: any) => {
            return v ? '' : '请输入图形验证结果'
          },
          _error: ''
        },
        {
          key: 'code',
          slot: true,
          label: '验证码',
          hidden: true,
          required: false,
          validator: (v: any, rule: any) => {
            if (!v) {
              return '请输入' + rule.label
            } else {
              return v.length !== 4 ? '动态码长度为4字符' : ''
            }
          },
          _error: ''
        },
        {
          key: 'loginType',
          slot: true,
          noneClass: true
        }
      ],
      captcha: {
        id: '',
        svgData: ''
      },
      smsLoading: false,
      countdown: 0,

      isNormalLogin: false,
      countdownHandle: 0
    }
  },

  created() {
    window._testComp0 = this
    if (this.isLogin) {
      this.afterLogin()
    }
    this.isNormalLogin = this.$route.query.mode === 'normal'
  },

  computed: {
    countdownText() {
      return this.countdown + 'S后获取'
    },
    ...mapState(useAuthStore, {
      isLogin: 'isLogin'
    })
  },

  methods: {
    afterLogin() {
      const redirect = this.$route.query.redirect as string
      if (redirect) {
        if (redirect.startsWith('http')) {
          window.location.replace(decodeURIComponent(redirect))
        } else {
          this.$router.replace({ path: redirect })
        }
      } else {
        this.$router.replace({ name: 'home' })
      }
    },

    onChangeLoginType(otherType: string) {
      const type = this.formData.loginType === 'pw' ? otherType : 'pw'
      const isPwType = type === 'pw'
      const isCreateType = type === 'create'
      this.formData.loginType = type

      let item = this.formRules.find((o) => o.key === 'name') as any
      item.hidden = !isCreateType
      item.required = isCreateType

      item = this.formRules.find((o) => o.key === 'pw')
      item.hidden = !isPwType && !isCreateType
      item.required = isPwType || isCreateType

      item = this.formRules.find((o) => o.key === 'pw2')
      item.hidden = !isCreateType
      item.required = isCreateType

      item = this.formRules.find((o) => o.key === 'code')
      item.hidden = isPwType
      item.required = !isPwType
      this.formData.code = ''

      item = this.formRules.find((o) => o.key === 'captchaValue')
      item.hidden = isPwType
      item.required = !isPwType

      if (!isPwType || isCreateType) {
        this.onGetCaptcha()
      }

      const formComp = this.$refs.form as any
      formComp.clearErrors()
    },
    onGetCaptcha() {
      apiGetData(apiURL.captcha).then((resp) => {
        const { key: id, svgData } = resp.data
        this.captcha = { id, svgData }
      })
    },
    onGetSmsCode() {
      const formComp = this.$refs.form as any
      formComp.validateFields(['phone', 'captchaValue'], (errors: any) => {
        if (errors) {
          return
        }
        this.smsLoading = true
        const params = {
          mobile: this.formData.phone,
          key: this.captcha.id,
          code: this.formData.captchaValue
        }
        apiPostData(apiURL.smsCode, params)
          .then(() => {
            this.countdown = 60
            clearInterval(this.countdownHandle)
            this.countdownHandle = setInterval(() => {
              this.countdown--
              if (this.countdown === 0) {
                clearInterval(this.countdownHandle)
              }
            }, 1000)
          })
          .finally(() => {
            this.smsLoading = false
          })
      })
    },

    onSubmit() {
      const formComp = this.$refs.form as any
      formComp.validate((errors: any) => {
        if (errors) {
          return
        }
        this.isRequesting = true

        const { phone, pw, code, name, loginType } = this.formData
        const params = { account: phone } as any
        if (code) {
          params.code = code
          params.pw = '******'
        } else {
          params.pw = pw
        }

        const isCreateType = loginType === 'create'
        if (isCreateType) {
          params.name = name
        } else if (this.isNormalLogin) {
          params.type = 1
        }

        const method = isCreateType ? this.createUser : this.login
        method(params)
          .then(() => {
            this.$toast('登录成功')
            this.afterLogin()
          })
          .finally(() => {
            this.isRequesting = false
          })
      })
    },

    ...mapActions(useAuthStore, {
      createUser: 'createUser',
      login: 'login'
    })
  },
  beforeUnmount() {
    clearInterval(this.countdownHandle)
  }
})
</script>

<style lang="scss" scoped>
@import '@/ui/style/const.scss';

.login {
  .login-captcha {
    display: flex;
    flex-direction: row;
    align-items: center;
    input {
      flex: 1;
    }
    .svg-box {
      display: inline-block;
      width: 150px;
      height: 39px;
      overflow: hidden;
      ::v-deep {
        svg {
          width: 100%;
          height: 100%;
        }
      }
    }
  }
  .login-code {
    display: flex;
    flex-direction: row;
    align-items: center;
    input {
      flex: 1;
    }
    .code-divider {
      margin: 0 1rem;
      width: 1px;
      height: 1.6rem;
      background-color: rgb(151, 151, 151);
    }
    .code-countdown {
      display: inline-block;
      width: 6rem;
      color: rgb(167, 167, 167);
    }
  }
  .login-type {
    display: flex;
    flex-direction: row;
    margin-top: 1rem;
    .right {
      flex: 1;
      text-align: right;
    }
    .left {
      flex: 1;
      text-align: left;
    }
  }
  .login-button {
    margin-top: 2rem;
  }
}
</style>
